package domain;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.swing.ImageIcon;

import pagemaker.ExternalProgramException;
import pagemaker.MuPDFPageMaker;

public class PDFdoc implements Comparable<PDFdoc> {

    int            currentPage, docNumber;
    String         title, pdfFilename;
    List<String>   tags, authors;
    MuPDFPageMaker pdf;

    /**
     * @param file
     * @param nbPages
     * @throws ExternalProgramException
     * @throws IOException
     */
    private PDFdoc(String file, int nbPages) {
        try {
            pdfFilename = file;
            File pdfFile = new File(file);
            // title = pdfFile.getName();
            pdf = new MuPDFPageMaker(pdfFile, nbPages);
        } catch (IOException | ExternalProgramException e) {
            e.printStackTrace();
        }

    }

    private PDFdoc(File file, int nbPages) {
        try {
            pdfFilename = file.getPath();
            pdf = new MuPDFPageMaker(file, nbPages);
        } catch (IOException | ExternalProgramException e) {
            e.printStackTrace();
        }
    }

    private PDFdoc(File file) {
        try {
            pdfFilename = file.getPath();
            pdf = new MuPDFPageMaker(file);
        } catch (IOException | ExternalProgramException e) {
            e.printStackTrace();
        }
    }

    private PDFdoc() {
        super();
    }

    /**
     * Returns an instance of PDFdoc.
     * 
     * @param f
     *            a File
     * @return PDFdoc
     * @requires Parameter f is a PDF file that exists on the file system.
     * @throws IOException
     * @throws ExternalProgramException
     */
    public static PDFdoc makePDFdoc(File f) throws IOException,
            ExternalProgramException {
        return new PDFdoc(f);
    }

    /**
     * Returns the set of tags as a string, separated by the given separator.
     * 
     * @param separator
     * @return
     */
    public String tagsToString(String separator) {
        StringBuilder sb = new StringBuilder();
        for (String tag : tags) {
            sb.append(tag);
            sb.append(", ");
        }
        return sb.substring(0,sb.length()-2);
    }

    /**
     * Returns the set of authors as a string, separated by the given separator.
     * 
     * @param separator
     * @return
     */
    public String authorsToString(String separator) {
        StringBuilder sb = new StringBuilder();
        for (String tag : authors) {
            sb.append(tag);
            sb.append(", ");
        }
        return sb.substring(0,sb.length()-2);
    }

    /**
     * Sets the title of the document.
     * 
     * @param title
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * @return the title of the document.
     */
    public String getTitle() {
        if (this.title == null){
            title = pdfFilename.substring(pdfFilename.lastIndexOf('/')+1, pdfFilename.length());
        }
        return title;
    }

    /**
     * @return The number of the document. (unique ID).
     */
    public int getDocumentNumber() {
        return this.docNumber;
    }

    public void setDocumentNumber(int docNumber) {
        this.docNumber = docNumber;
    }

    /**
     * Given a string that contains tags separated by the given separator, adds
     * the tags to the document.
     * 
     * @param tagsString
     */
    public void addTags(String tagsString, String separator) {
        this.tags = Arrays.asList(tagsString.split(separator));
    }

    /**
     * Given a string that contains authors names separated by the given
     * separator, adds the authors to the document.
     * 
     * @param authors
     * @param separator
     */
    public void setAuthors(String authors, String separator) {
        this.authors = Arrays.asList(authors.split(separator));
    }

    /**
     * Returns an ImageIcon that represent the current page.
     * 
     * @return
     * @throws IOException
     * @throws ExternalProgramException
     */
    public ImageIcon getCurrentPage() throws IOException,
            ExternalProgramException {
        return pdf.getPage(currentPage, 20);
    }

    /**
     * Returns an ImageIcon that represent the next page.
     * 
     * @return
     * @throws IOException
     * @throws ExternalProgramException
     * @requires getNbPages() > 0
     */
    public ImageIcon getNextPage() throws IOException, ExternalProgramException {
        return pdf.getPage(currentPage + 1, 20);
    }

    /**
     * Returns an ImageIcon that represent the previous page.
     * 
     * @return
     * @throws IOException
     * @throws ExternalProgramException
     */
    public ImageIcon getPreviousPage() throws IOException,
            ExternalProgramException {
        return pdf.getPage(currentPage - 1, 20);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(pdfFilename);
        sb.append(";");
        sb.append(docNumber);
        sb.append(";");
        sb.append(title);
        sb.append(";");
        sb.append(tagsToString(", "));
        // sb.append(";");
        // sb.append(authorsToString(", "));
        sb.append("\n");
        return sb.toString();
    }

    @Override
    public int compareTo(PDFdoc o) {
        // TODO: RNA - Não sei se será isto que se quer.
        return this.getDocumentNumber() - o.getDocumentNumber();
    }

    /**
     * Returns the number of pages of the document.
     * 
     * @return
     */
    public int getNumberOfPages() {
        return pdf.getNumberOfPages();
    }

    /**
     * Returns the number of the current page.
     * 
     * @return
     */
    public int getCurrentPageNumber() {
        return currentPage;
    }
}